<?php
/**
 * @version		$Id: packer.php 107 2011-02-26 16:32:11Z happy_noodle_boy $
 * @package		JCE
 * @copyright	Copyright (C) 2009 Ryan Demmer. All rights reserved.
 * @copyright	Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.
 * @license		GNU/GPL
 * This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 */

defined('_JEXEC') or die('RESTRICTED');

class WFPacker extends JObject
{
	var $files 		= array();
    
    var $type		= 'javascript';
    
    var $start 		= '';
    
    var $end 		= '';
    
    /**
     * Constructor activating the default information of the class
     *
     * @access	protected
     */
    function __construct($config = array()){
    	$this->setProperties($config);
    }
    
    function setFiles($files = array())
    {
    	$this->files = $files;
    }
    
    function getFiles()
    {
    	return $this->files;
    }
    
	function setContentStart($start = '')
    {
    	$this->start = $start;
    }
    
    function getContentStart()
    {
    	return $this->start;
    }
    
	function setContentEnd($end = '')
    {
    	$this->end = $end;
    }
    
    function getContentEnd()
    {
    	return $this->end;
    }
    
    function setType($type)
    {
    	$this->type = $type;
    }
    
    function getType()
    {
    	return $this->type;
    }
    
	function pack($cache = false, $compress = false, $gzip = false)
	{		
		jimport('joomla.filesystem.folder');
		jimport('joomla.filesystem.file');
		
		$type = $this->getType();
		
		// Headers
		header("Content-type: text/". $type ."; charset: UTF-8");
		header("Cache-Control: must-revalidate");
		header("Vary: Accept-Encoding");  // Handle proxies
		header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600 * 24 * 10) . " GMT");
		
		$cachepath 	= JPATH_SITE.DS.'cache';

		$cachefile  = '';
		
		$files		= $this->getFiles();

		// Setup cache info
		if ($cache) {
			$key = implode('', $files);
	
			$key = md5($key);
	
			if ($gzip) {
				$cachefile = $cachepath . "/jce_" . $key . ".gz";
			} else {
				$ext = 'js';
				
				if ($type == 'css') {
					$ext = 'css';
				}
				
				$cachefile = $cachepath . "/jce_" . $key . "." . $ext;
			}
		}
		
		// Check if it supports gzip
		if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
			$encodings = explode(',', strtolower(preg_replace("/\s+/", "", $_SERVER['HTTP_ACCEPT_ENCODING'])));
	
		if ((in_array('gzip', $encodings) || in_array('x-gzip', $encodings) || isset($_SERVER['---------------'])) && function_exists('ob_gzhandler') && !ini_get('zlib.output_compression')) {
			$enc = in_array('x-gzip', $encodings) ? "x-gzip" : "gzip";
		} else {
			// flag $gzip false regardless of parameter
			$gzip = false;
		}
	
		// Use cached file disk cache
		if ($cache && $cachefile) {
			if (JFile::exists($cachefile)) {
				if ($gzip) {
					header("Content-Encoding: " . $enc);
				}
		
				die(@JFile::read($cachefile));
			}
			
		}
		
		$content = $this->getContentStart();
		
		foreach ($files as $file) {
			$content .= $this->getText($file);
		}
		
		$content .= $this->getContentEnd();

		// Generate GZIP'd content
		if ($gzip) {
			// pack javascript
			if ($compress) {
				if ($this->getType() == 'javascript') {
					require_once(dirname(__FILE__).DS.'jsmin.php');
				
					$content = trim(JSMin::minify($content));
				}
				
				if ($this->getType() == 'css') {
					require_once(dirname(__FILE__).DS.'cssmin.php');
				
					$content = CssMin::minify($content);
				}
			}

			header("Content-Encoding: " . $enc);
			$data = gzencode($content, 9, FORCE_GZIP);
			
			// Write gz file
			if ($cache && $key != "") {
				@JFile::write($cachefile, $data);
			}

			// Stream to client
			die($data);
		} else {
			if ($compress) {
				if ($type == 'javascript') {
					require_once(dirname(__FILE__).DS.'jsmin.php');
				
					$content = trim(JSMin::minify($content));
				}
				
				if ($type == 'css') {
					require_once(dirname(__FILE__).DS.'cssmin.php');
				
					$content = CssMin::minify($content);
				}
			}
			// Stream uncompressed content
			die($content);
		}
	}
	
	/**
	 * Import CSS from a file
	 * @param file File path where data comes from
	 * @param $data Data from file
	 */
	function importCss($data)
	{
		if (preg_match_all('#@import url\([\'"]?([^\'"\)]+)[\'"]?\);#i', $data, $matches)) {
			
			$data = '';
			
			foreach ($matches[1] as $match) {				
				$data .= $this->getText(realpath($this->get('_cssbase') . DS . $match));
			}
			
			return $data;
		}
		
		return '';
	}
	
	function getText($file)
	{				
		if ($file) {	
			
			if ($text = @JFile::read($file)) {
				// process css files
				if ($this->getType() == 'css') {

					if (strpos($text, '@import') !== false) {
						// store the base path of the current file
						$this->set('_cssbase', dirname($file));
						
						// process import rules
						$text = $this->importCss($text) . preg_replace('#@import url\([\'"]?([^\'"\)]+)[\'"]?\);#i', '', $text);
					}
					
					// store the base path of the current file
					$this->set('_imgbase', dirname($file));
					
					// process urls
					$text = preg_replace_callback('#url\s?\([\'"]?([^\'"\))]+)[\'"]?\)#', array('WFPacker', 'processPaths'), $text);
				}

				return $text;
			}
		}
		
		return '';
	}
	
	function processPaths($data)
	{							
		$path = str_replace(JPATH_SITE, '', realpath($this->get('_imgbase') . DS . $data[1]));

		if ($path) {
			return "url('". JURI::root(true) . str_replace(DS, '/', $path) . "')";
		}
		
		return "url('". $data[1] . "')";
	}
}
?>